package org.scribe.provider.model;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * This interface represents a repository of Applications, Users, Tokens, and Nonces used
 * with the OAuth Workflow.
 * @author Keith W. Boone
 */
public interface Repository {

	// A variety of constants that can be used by a repository.  Override these values in your
	// repository implementation if you want to use different values.
	/**
	 * Max age of a nonce before it can be discarded.
	 */
	public static long MAX_NONCE_AGE = 300L;
	
	/**
	 * Max age of a client token in seconds (five years).
	 */
	public static long MAX_CLIENT_TOKEN_AGE = 5 * 365 * 24 * 3600l;
	
	/**
	 * Max age of a request token in seconds (10 minutes).
	 */
	public static long MAX_REQUEST_TOKEN_AGE = 600l;
	
	/**
	 * Max age of a temporary token in seconds (10 minutes).
	 */
	public static long MAX_TEMPORARY_TOKEN_AGE = 600l;
	
	/**
	 * Max age of an access token in seconds (1 year).
	 */
	public static long MAX_ACCESS_TOKEN_AGE = 365 * 24 * 3600l;
	
	/**
	 * Age upon which you should reauthorize an existing token in seconds (1 week)
	 */
	public static long REAUTHORIZATION_AGE = 7 * 24 * 60 * 60;
	
	/**
	 * Length of a secret as generated by this repository.
	 */
	public static int SECRET_LENGTH = 24;
	
	/**
	 * Length of a token as generated by this repository.
	 */
	public static int TOKEN_LENGTH = 24;

	/**
	 * Get the token associated with the particular key from the repository.
	 * @param key	The key assigned to the token.
	 * @return	The token associated with this key.
	 */
	public Token getToken(String key);
	
	/**
	 * Removes a token from the repository.  This method is used to delete a token.
	 * @param token	The token to remove.
	 */
	public void remove(Token token);
	
	/**
	 * Create a new client token for the specified application.
	 * @param app	The application to create the token for.
	 * @return	A new client token associated with the application.
	 */
	public Token createClientToken(Application app);
	
	/**
	 * Create a new request token to be associated with a particular 
	 * application and callback.
	 * @param app	The application to create the request token for.
	 * @param callback	The URL to use to call back to the application
	 * @return	The new request token
	 */
	public Token createRequestToken(Application app, String callback);
	
	/**
	 * Change the request token into a Temporary token to be associated 
	 * with a particular application and user.  
	 * @param requestToken	The requestToken to be converted into a temporary token.
	 * @param user	The user who has authorized the application.
	 * @param roles	The set of roles that user has authorized.
	 */
	public void createTemporaryToken(Token requestToken, User user, Collection<String> roles);
	
	/**
	 * Create a new access token to be associated with a particular
	 * application and user.
	 * @param app	The application requesting the temporary token.
	 * @param user	The user who has authorized the application.
	 * @param roles	The set of roles that user has authorized.
	 * @return The new access token.
	 */
	public Token createAccessToken(Application app, User user, Collection<String> roles);
	
	/**
	 * Has the specified nonce been used before.
	 * @param nonce  The nonce to check.
	 * @return  True if this nonce has been previously used in a request, false otherwise.
	 */
	public boolean isNonceUsed(String nonce);
	
	
	/**
	 * Save the nonce so that it cannot be used again.
	 * @param nonce  The nonce to save.
	 */
	public void saveNonce(String nonce);
	
	
	/**
	 * Get a user by their identifier.
	 * @param userId The user identifier
	 * @return The user associated with this identifier, or null if the user cannot be found.
	 */
	public User getUser(String userId);
	
	/**
	 * Get an application by its identifier.
	 * @param appId The application identifier
	 * @return The application associated with this identifier, or null if it cannot be found.
	 */
	public Application getApplication(String appId);
	

}
